

#include <material/materialmanager.h>
#include <material/shadereditor/shaderoverview.h>
#include <material/shadereditor/shadereditordialog.h>
#include <material/shadereditor/shadertreemodel.h>
#include <session.h>
#include <assert.h>
#include <config.h>

#include <qmessagebox.h>
#include <qsortfilterproxymodel.h>

class cceMaterialShaderFilterModel : public QSortFilterProxyModel
{
private:
  QString	_filter;
  cceMaterialShaderTreeModel*	_model;
public:
  cceMaterialShaderFilterModel (QObject* parent, cceMaterialShaderTreeModel* model)
    : QSortFilterProxyModel (parent)
    , _model (model)
  {
    setSourceModel (model);
    setSortCaseSensitivity(Qt::CaseInsensitive);
    setSortRole(Qt::DisplayRole);
  }

  void SetFilter (const QString &filter)
  {
    _filter = filter;
    invalidateFilter ();
  }

  bool filterAcceptsRow (int source_row, const QModelIndex &source_parent) const
  {
    QString name = _model->GetShaderName (source_row) + _model->GetShaderTypeName(source_row);
    if (name.isNull ()) return false;

    return name.contains (_filter, Qt::CaseInsensitive);
  }
};

cceMaterialShaderOverview::cceMaterialShaderOverview (QWidget* parent)
  : cceMaterialOverviewAbstract (parent)
{
  _gui.setupUi(this);

  _model = new cceMaterialShaderTreeModel (cceSession::Get ()->GetMaterialManager ());
  _proxyModel = new cceMaterialShaderFilterModel (this, _model);
  _gui.treeView->setModel (_proxyModel);
  _gui.treeView->sortByColumn(1, Qt::AscendingOrder);

	connect (_gui.treeView->selectionModel (), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
           this, SLOT(TreeViewSelectionChanged (const QItemSelection&, const QItemSelection&)));

  UpdateButtonState ();
}

void cceMaterialShaderOverview::UpdateButtonState ()
{
  QModelIndex index = _gui.treeView->currentIndex ();
  bool enable = index.isValid () && index.internalPointer ();

  _gui.pushButtonAdd->setEnabled (true);
  _gui.pushButtonRemove->setEnabled (enable);
  _gui.pushButtonEdit->setEnabled (enable);
}



cceMaterialEditorAbstract* cceMaterialShaderOverview::CreateEditor(cceMaterialItem *item)
{
  if (item->GetItemType() != cceMaterialItem::ItemType_Shader)
    {
      return 0;
    }

  cceMaterialShader* shader = static_cast<cceMaterialShader*>(item);

  cceMaterialShaderEditorDialog* editor = new cceMaterialShaderEditorDialog (this);
  editor->SetShader(shader);

  return editor;
}


void cceMaterialShaderOverview::Edit(const QModelIndex &srcIndex)
{
  if (!srcIndex.isValid())
    {
			UpdateButtonState();
      return;
    }

  QModelIndex index = _proxyModel->mapToSource(srcIndex);
	if (!index.isValid())
		{
			UpdateButtonState();
			return;
		}

  cceMaterialShader* shader= static_cast<cceMaterialShader*>(index.internalPointer ());
  assert (shader);

  emit ShowEditor(shader);
}


void cceMaterialShaderOverview::on_pushButtonAdd_clicked ()
{
  cceMaterialShader* shader = new cceMaterialShader ();
  shader->SetType (cceMaterialShader::Type_Vertex);
  shader->SetName ("unnamed.vs");
  shader->SetNew (true);

  emit ShowEditor(shader);
}

void cceMaterialShaderOverview::on_pushButtonRemove_clicked ()
{
  QModelIndex index = _gui.treeView->currentIndex ();
	if (!index.isValid())
		{
			UpdateButtonState();
			return;
		}

  index = _proxyModel->mapToSource(index);
	if (!index.isValid())
		{
			UpdateButtonState();
			return;
		}


  cceMaterialShader* shader= static_cast<cceMaterialShader*>(index.internalPointer ());
  assert (shader);

  int result = QMessageBox::question (this,
    "Delete shader- " CCE_TOOL_NAME,
    tr ("Are you sure you want to delete the shader '%1'?").arg (shader->GetName ()),
    QMessageBox::Ok, QMessageBox::Cancel);
  if (result == QMessageBox::Ok)
    {
      cceSession::Get ()->GetMaterialManager()->RemoveShader (shader);
    }
}


void cceMaterialShaderOverview::on_pushButtonEdit_clicked ()
{
  QModelIndex index = _gui.treeView->selectionModel()->currentIndex();
  if (!index.isValid())
    {
      return;
    }

  Edit (index);
}

void cceMaterialShaderOverview::on_treeView_activated(const QModelIndex &index)
{
  if (!index.isValid())
    {
      return;
    }
  Edit (index);
}

void cceMaterialShaderOverview::on_lineEditFilter_textChanged (const QString &text)
{
  _proxyModel->SetFilter (text);
}


void cceMaterialShaderOverview::on_pushButtonClearFilter_clicked ()
{
  _gui.lineEditFilter->setText ("");
}


void cceMaterialShaderOverview::TreeViewSelectionChanged (const QItemSelection&, const QItemSelection&)
{
  UpdateButtonState ();
}
